package controller

import (
	"bookmark-web/logic"
	"bookmark-web/models"
	"bookmark-web/utils"
	"log"
	"strconv"

	"github.com/gin-gonic/gin"
)

// SetupBookmarkRouter 设置收藏相关路由
func SetupBookmarkRouter(api *gin.RouterGroup) {
	bookmark := api.Group("/bookmark")
	{
		bookmark.POST("/", CreateBookmark)                            // 创建收藏
		bookmark.GET("/:id", GetBookmark)                             // 获取单个收藏
		bookmark.GET("/", GetAllBookmarks)                            // 获取收藏列表（无分页）
		bookmark.GET("/category/:categoryId", GetBookmarksByCategory) // 根据分类获取收藏
		bookmark.PUT("/:id", UpdateBookmark)                          // 更新收藏
		bookmark.DELETE("/:id", DeleteBookmark)                       // 删除收藏
		bookmark.POST("/batch", BatchOperateBookmarks)                // 批量操作收藏
		bookmark.GET("/preview", GetURLPreview)                       // 获取网址预览
		bookmark.POST("/:id/visit", VisitBookmark)                    // 记录访问
	}
}

// CreateBookmark 创建网址收藏控制器
// @Summary 创建书签
// @Description 创建新的网址书签
// @Tags 书签相关
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param data body models.BookmarkCreateRequest true "书签信息"
// @Success 200 {object} utils.Response "创建成功"
// @Router /bookmark [post]
func CreateBookmark(c *gin.Context) {
	// 1. 获取用户ID
	userID := getUserID(c)

	// 2. 绑定请求参数
	var req models.BookmarkCreateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		log.Printf("参数绑定失败: %v", err)
		utils.InvalidParams(c, "请求参数格式错误")
		return
	}

	// 3. 调用业务逻辑层创建收藏
	bookmarkResp, err := logic.CreateBookmark(&req, userID)
	if err != nil {
		log.Printf("创建收藏失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 4. 返回成功响应
	utils.Success(c, "创建收藏成功", bookmarkResp)
}

// GetBookmark 获取单个收藏控制器
// @Summary 获取单个书签
// @Description 根据ID获取单个书签
// @Tags 书签相关
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path string true "书签ID"
// @Success 200 {object} utils.Response "获取成功"
// @Router /bookmark/{id} [get]
func GetBookmark(c *gin.Context) {
	// 1. 获取用户ID
	userID := getUserID(c)

	// 2. 获取收藏ID
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		utils.InvalidParams(c, "收藏ID格式错误")
		return
	}

	// 3. 调用业务逻辑层获取收藏
	bookmarkResp, err := logic.GetBookmarkByID(uint(id), userID)
	if err != nil {
		log.Printf("获取收藏失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 4. 返回成功响应
	utils.Success(c, "获取收藏成功", bookmarkResp)
}

// GetBookmarksList 获取收藏列表控制器（分页）
func GetBookmarksList(c *gin.Context) {
	// 1. 获取用户ID
	userID := getUserID(c)

	// 2. 绑定查询参数
	var req models.BookmarkQueryRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		log.Printf("参数绑定失败: %v", err)
		utils.InvalidParams(c, "请求参数格式错误")
		return
	}

	// 3. 调用业务逻辑层获取收藏列表
	listResp, err := logic.GetBookmarksList(userID, &req)
	if err != nil {
		log.Printf("获取收藏列表失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 4. 返回成功响应
	utils.Success(c, "获取收藏列表成功", listResp)
}

// GetAllBookmarks 获取所有收藏控制器（无分页）
// @Summary 获取所有书签
// @Description 获取所有书签列表（无分页）
// @Tags 书签相关
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} utils.Response "获取成功"
// @Router /bookmark [get]
func GetAllBookmarks(c *gin.Context) {
	// 1. 获取用户ID
	userID := getUserID(c)

	// 2. 调用业务逻辑层获取所有收藏
	bookmarks, err := logic.GetAllBookmarks(userID)
	if err != nil {
		log.Printf("获取所有收藏失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 3. 返回成功响应
	utils.Success(c, "获取所有收藏成功", bookmarks)
}

// GetBookmarksByCategory 根据分类获取收藏列表控制器
// @Summary 根据分类获取收藏
// @Description 根据分类ID获取该分类下的所有收藏
// @Tags 书签相关
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param categoryId path string true "分类ID"
// @Success 200 {object} utils.Response "获取成功"
// @Router /bookmark/category/{categoryId} [get]
func GetBookmarksByCategory(c *gin.Context) {
	// 1. 获取用户ID
	userID := getUserID(c)

	// 2. 获取分类ID
	idStr := c.Param("categoryId")
	categoryID, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		utils.InvalidParams(c, "分类ID格式错误")
		return
	}

	// 3. 调用业务逻辑层获取分类收藏
	bookmarks, err := logic.GetBookmarksByCategory(uint(categoryID), userID)
	if err != nil {
		log.Printf("获取分类收藏失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 4. 返回成功响应
	utils.Success(c, "获取分类收藏成功", bookmarks)
}

// UpdateBookmark 更新收藏控制器
func UpdateBookmark(c *gin.Context) {
	// 1. 获取用户ID
	userID := getUserID(c)

	// 2. 获取收藏ID
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		utils.InvalidParams(c, "收藏ID格式错误")
		return
	}

	// 3. 绑定请求参数
	var req models.BookmarkUpdateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		log.Printf("参数绑定失败: %v", err)
		utils.InvalidParams(c, "请求参数格式错误")
		return
	}

	// 4. 调用业务逻辑层更新收藏
	bookmarkResp, err := logic.UpdateBookmark(uint(id), &req, userID)
	if err != nil {
		log.Printf("更新收藏失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 5. 返回成功响应
	utils.Success(c, "更新收藏成功", bookmarkResp)
}

// DeleteBookmark 删除收藏控制器
func DeleteBookmark(c *gin.Context) {
	// 1. 获取用户ID
	userID := getUserID(c)

	// 2. 获取收藏ID
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		utils.InvalidParams(c, "收藏ID格式错误")
		return
	}

	// 3. 调用业务逻辑层删除收藏
	err = logic.DeleteBookmark(uint(id), userID)
	if err != nil {
		log.Printf("删除收藏失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 4. 返回成功响应
	utils.Success(c, "删除收藏成功", nil)
}

// BatchOperateBookmarks 批量操作收藏控制器
func BatchOperateBookmarks(c *gin.Context) {
	// 1. 获取用户ID
	userID := getUserID(c)

	// 2. 绑定请求参数
	var req models.BookmarkBatchRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		log.Printf("参数绑定失败: %v", err)
		utils.InvalidParams(c, "请求参数格式错误")
		return
	}

	// 3. 调用业务逻辑层批量操作
	err := logic.BatchOperateBookmarks(&req, userID)
	if err != nil {
		log.Printf("批量操作失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 4. 返回成功响应
	var message string
	switch req.Action {
	case "delete":
		message = "批量删除成功"
	case "move":
		message = "批量移动成功"
	default:
		message = "批量操作成功"
	}
	utils.Success(c, message, nil)
}

// GetURLPreview 获取网址预览控制器
func GetURLPreview(c *gin.Context) {
	// 1. 获取URL参数
	url := c.Query("url")
	if url == "" {
		utils.InvalidParams(c, "URL参数不能为空")
		return
	}

	// 2. 调用业务逻辑层获取预览
	preview, err := logic.GetURLPreview(url)
	if err != nil {
		log.Printf("获取网址预览失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 3. 返回成功响应
	utils.Success(c, "获取预览成功", preview)
}

// VisitBookmark 访问收藏控制器（增加访问次数）
func VisitBookmark(c *gin.Context) {
	// 1. 获取用户ID
	userID := getUserID(c)

	// 2. 获取收藏ID
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		utils.InvalidParams(c, "收藏ID格式错误")
		return
	}

	// 3. 调用业务逻辑层记录访问
	err = logic.VisitBookmark(uint(id), userID)
	if err != nil {
		log.Printf("记录访问失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 4. 返回成功响应
	utils.Success(c, "访问记录成功", nil)
}

// BookmarkPage 收藏管理页面
func BookmarkPage(c *gin.Context) {
	c.HTML(200, "bookmark.html", gin.H{
		"title": "收藏管理",
	})
}
